package org.example.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.exception.exception.MassageException;
import org.example.mapper.UserMapper;
import org.example.pojo.*;
import org.example.pojo.vo.*;
import org.example.service.UserService;
import org.example.utils.*;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class UserServiceImpl implements UserService {
    private final UserMapper userMapper;
    //线程池
    private final ThreadPoolTaskExecutor customThreadPool;
    // 发送http请求
    private final RestTemplate restTemplate;
    private final HttpRequestUtil httpRequestUtil;


    //注册
    public User register(User user) {
        //获取当前用户信息
        Map<String, Object> stringtoken = ThreadLocalUtil.get();
        //判断是不是管理员
        if (stringtoken.get("isSuper").equals(false)) {
            throw new MassageException(KuaiZuConst.RETURN_ERROR_CODE, "您不是炒鸡管理员,无法注册");
        }
        log.info("用户注册");
        //判断用户是否注册
        User u = userMapper.selectUserInfo(user);
        if (u != null) {
            throw new MassageException(KuaiZuConst.RETURN_ERROR_CODE, "用户已注册");
        }
        //设置初始密码
        //密码加密
        String str = "Kuaizu" + randomString();
        String password = Md5Util.getMD5String(str);
        user.setPassword(password);
        Date date = new Date();
        //设置创建时间
        user.setCreateTime(date);
        user.setIsSuper(false);
        user.setIsDefPassword(KuaiZuConst.STRING_DEF_NUMBER);
        //注册
        userMapper.insertUser(user);
        String time = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss");
        String log = logText("用户注册", stringtoken.get("name").toString(), null, true, time);
        UserServiceImpl.log.info("初始密码为{}", str);
        //数据库写入log
        OperationLog log1 = new OperationLog();
        log1.setUserId((Integer) stringtoken.get("id"));
        log1.setOperationType(true);
        log1.setOperationUserId(0);
        log1.setCreateTime(new Date());
        log1.setText(log);
        userMapper.insertUserProofStart(log1);
        //注册成功后返回用户信息
        user.setPassword(str);
        return user;
    }

    //登陆
    @Override
    public UserVo login(User user) {
        log.info("用户登陆");
        //给密码加密
        String password = Md5Util.getMD5String(user.getPassword());
        user.setPassword(password);
        User u = userMapper.selectUserInfo(user);
        if (u == null) {
            throw new MassageException(KuaiZuConst.RETURN_ERROR_CODE, "用户不存在,或者账号密码错误");
        }
        //更新用户登陆时间
        Date date = new Date();
        u.setUpdateTime(date);
        //开启线程更新登录时间
        customThreadPool.execute(() -> {
            userMapper.updateLoginTime(u.getId(), date);
        });
        //将对象转成map集合
        ObjectMapper objectMapper = new ObjectMapper();
        Map map = objectMapper.convertValue(u, Map.class);
        String token = JwtUtil.genToken(map);
        //使用hutool将user对象转成userVo对象
        UserVo userVo = BeanUtil.copyProperties(u, UserVo.class);
        userVo.setToken(token);
        return userVo;
    }

    //去服务器查询先关用户
    @Override
    public ResponseStudentOv SelectBySchoolIdFormKuaiZu(Integer schoolId) {

        /*
         * "{"code":200,
         * "message":"查询成功",
         * "data":{
         *   "0":[
         *       {"userId":10,
         *           "openId":"oftesttesttesttesttesttest10",
         *           "proofId":4,"userPhoto":"2025/06/17/6850d2cce4b02b5a7a48a894.jpeg","certificationInfo":null,"schoolName":"丽水职业技术学院","major":"信息管理和信息系统","userProofStart":0}]
         * `,"1":[{"userId":11,"openId":"oftesttesttesttesttesttest11","proofId":5,"userPhoto":"2025/06/17/6850d2e8e4b02b5a7a48a895.jpg","certificationInfo":null,"schoolName":"丽水职业技术学院","major":"信息管理和信息系统","userProofStart":1}],"2":[{"userId":12,"openId":"oftest"[truncated 182 chars]; line: 1, column: 37]
         * */
        ResponseStudentOv re = httpRequestUtil.getRESTful("/hou/querystudent", schoolId.toString(), new ResponseStudentOv(), ResponseStudentOv.class);
        return re;
    }

    @Override
    public ResponseSchoolListOv SelectSchoolList(String name) {
        Map<String, String> nap = new HashMap<>();
        nap.put("name", name);
        ResponseSchoolListOv responseSchoolListOv = httpRequestUtil.postRequest("/user/school", nap, new ResponseSchoolListOv(), ResponseSchoolListOv.class);
        return responseSchoolListOv;
    }

    @Override
    public Object updateStudentStart(UserProofStart user) {
        log.info("审核用户{}", user);
        //从ThreadLocal获取当前用户的信息
        Map<String, Object> stringtoken = ThreadLocalUtil.get();
        //获取用户的openId
        log.info("用户{}", stringtoken);
        RequestPeviewParam param = new RequestPeviewParam();
        param.setOpenId(user.getOpenId());
        param.equals(user.getOpenId());
        param.setProofStart(user.getUserProofStart().toString().equals(KuaiZuConst.STRING_DEF_NUMBER));
        param.setText(user.getCertificationInfo());
        param.setReviewId((Integer) stringtoken.get("id"));
        param.setName((String) stringtoken.get("name"));
        boolean b = true;
        String s1;
        //发送请求
        try {
            Object o = httpRequestUtil.postRequest("/hou/reviewstudent", param, new Object(), Object.class);
        } catch (Exception e) {
            b = false;
            throw new MassageException(KuaiZuConst.RETURN_ERROR_CODE, "审核失败");
        } finally {
            s1 = "执行成功";
            if (!b) {
                s1 = "执行失败";
            }
            //数据库写入log
            OperationLog log = new OperationLog();
            log.setUserId((Integer) stringtoken.get("id"));
            log.setOperationType(user.getUserProofStart().toString().equals(KuaiZuConst.STRING_DEF_NUMBER));
            log.setOperationUserId(user.getUserId());
            log.setCreateTime(new Date());
            //创建当前时间对象并且格式化成yyyy-MM-dd HH:mm:ss
            String time = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss");
            log.setText(logText(s1, (String) stringtoken.get("name"), user.getOpenId(), user.getUserProofStart().toString().equals(KuaiZuConst.STRING_DEF_NUMBER), time));
            userMapper.insertUserProofStart(log);
        }
        return "审核成功";
    }

    @Override
    public Object updatePassword(UpdatePassWord updatePassWord) {
        String newPassword = updatePassWord.getNewPassword();
        //密码加密
        newPassword = Md5Util.getMD5String(newPassword);
        //更新密码
        userMapper.updatePassword(updatePassWord.getId(), newPassword, KuaiZuConst.STRING_NOTDEF_NUMBER);
        return "更新成功";
    }

    //查询所有管理员信息
    @Override
    public Object adminlist() {
        List<User> users = userMapper.adminlist();
        Map<Integer, List<User>> map = users.stream().collect(Collectors.groupingBy(User::getSchoolCode));
        //查询学校信息
        ReqBean<String> reqBean = new ReqBean<>();
        ResponseSchoolListOv request = httpRequestUtil.getRequest("/user/school", null, new ResponseSchoolListOv(), ResponseSchoolListOv.class);
        List<School> schoos = request.getData();
        Map<Integer, String> map1 = schoos.stream().collect(Collectors.toMap(School::getId, School::getSchoolname));
        List<UserVo> userVos = new LinkedList<>();
        if (!CollUtil.isNotEmpty(map)) {
            log.error("学校分组集合异常");
            return null;
        }
        if (!CollUtil.isNotEmpty(map1)) {
            log.error("学校信息集合异常");
            return null;
        }
        map.forEach((k, v) -> {
            v.forEach(user -> {
                UserVo u = new UserVo();
                BeanUtil.copyProperties(user, u);
                u.setSchoolName(map1.get(k));
                userVos.add(u);
            });
        });
        //根据分组的学校
        return userVos;
    }

    // 查询所有学生信息
    @Override
    public StudentInfoOv SelectStudentList(StudentInfoListParam req) {
        //TODO案例 在这里
        // 1.因为不需额外操作,所以可以直接调用三方接口  这里返回的ov是根据后台返回的数据设置的,去掉状态码和状态信息,
        // 第一层必须是data才能自动转成对应的对象类型没有的,返回值有对象属性没有会忽略字段
        StudentInfoOv pb = httpRequestUtil.postRequest(
                "/hou/querystudentinfo/all",//请求路径
                //"/hou/test",
                req,//请求参数,注意要跟接口文档的参数保持一致
                new StudentInfoOv(),//请求蚕食返回值封装的对象
                StudentInfoOv.class//对象字节码文件
                //返回参数  [Source: (String)"{"code":200,"message":"查询成功","data":{"total":47,"items":[{"id":2144,"openid":"of5t47QAOBcZrFA6N0k39Bxm230s","phone":"13385484024","nickname":"final.","email":"3097405584@qq.com","school":2144,"grade":2,"major":1,"coverImage":"2025/06/17/6850d2e8e4b02b5a7a48a895.jpg","avatarUrl":"2025/06/17/6850d2cce4b02b5a7a48a894.jpeg","gender":null,"age":null,"personality":null,"mbti":"INFP","persona":"我呼呼","projectOrientation":"获奖","introduction":"以梦为马，越骑越傻。","certificationInfo":"0","createdAt":1749064379000,"[truncated 607 chars]; line: 1, column: 1]
        );
        //接口返回的数据添加对应页码参数
        pb.setPageSize(req.getPageSize());
        pb.setPageNum(req.getPageNum());
        return pb;
    }


    public Object reviewStudent(ReviewParam param) {
        boolean b = true;
        String s1;
        try {
            Object o = httpRequestUtil.postRequest("/hou/reviewstudent", param, new Object(), Object.class);
        } catch (Exception e) {
            b = false;
            throw new MassageException(KuaiZuConst.RETURN_ERROR_CODE, "审核失败");
        } finally {
            s1 = "执行成功";
            if (!b) {
                s1 = "执行失败";
            }
            OperationLog log = new OperationLog();
            log.setUserId(param.getReviewId());
            log.setOperationType(param.getProofStart());
            log.setOperationUserId(null);
            log.setCreateTime(new Date());
            String time = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss");
            log.setText(logText(s1, param.getName(), param.getOpenid(), param.getProofStart(), time));
            userMapper.insertUserProofStart(log);
        }
        return "审核成功";
    }


    @Override
    public Object updateUserInfo(UpdateUserInfoParam param) {
        httpRequestUtil.postRequest("/hou/updateUserInfo", param, null, null);
        return "修改成功";
    }
    //注销学生
    @Transactional
    @Override
    public Object delectStudent(DelectStudentParam param) {
        //TODO 注销学生
        userMapper.insertUserProofStart(LogInfoUtil.getLogInfo("注销用户", param.getText()));
        OperationLog log = new OperationLog();
        ReqBean<String> reqBean = new ReqBean<>();
        reqBean= httpRequestUtil.postRequest("/hou/userOffline", param, reqBean, ReqBean.class);
        return reqBean;
    }

    private String logText(String s, String name, String userId, boolean start, String time) {
        return s + "------->" + name + "审核用户openId-{" + userId + "} ,审核状态->{" + (start ? "同意审核" : "拒绝审核" + "}, 审核时间->{" + time + "}");
    }

    //随机密码生成
    private String randomString() {
        String str;
        //随机生成六个数据范围在STRING_SEED中的数据
        char[] chars = new char[6];
        for (int i = 0; i < 6; i++) {
            int random = (int) (Math.random() * KuaiZuConst.STRING_SEED.length);
            chars[i] = KuaiZuConst.STRING_SEED[random];
        }
        str = new String(chars);
        return str;
    }
}
